# -*- coding: utf-8 -*-
# @Author: Jerry
# @Date:   2022-02-23 10:13:12
# @Last Modified by:   Jerry
# @Last Modified time: 2022-03-01 15:31:15

# **********
'''
在图像处理中，由于每秒要处理大量操作，因此必须使代码不仅提供正确的解决方案，而且还必须以最快的方式提供。
你将学习
衡量代码的性能。
一些提高代码性能的技巧。
你将看到以下功能：cv.getTickCount，cv.getTickFrequency 等。

除了OpenCV，Python还提供了一个模块 time，这有助于衡量执行时间。
另一个模块 profile 有助于获取有关代码的详细报告，例如代码中每个函数花费了多少时间，调用了函数的次数等。
'''
import os
rootpath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
datapath = os.path.join(rootpath,'data')
imgpath = lambda name: os.path.join(datapath,name)

import numpy as np
import cv2 as cv
import time

# **********
'''
使用OpenCV衡量性能
cv.getTickCount() 函数返回从参考事件（如打开机器的那一刻）到调用此函数那一刻之间的时钟周期数。
因此，如果在函数执行之前和之后调用它，则会获得用于执行函数的时钟周期数。

cv.getTickFrequency() 函数返回时钟周期的频率或每秒的时钟周期数。
'''
# 因此，要找到执行时间（以秒为单位），你可以执行以下操作：
e1 = cv.getTickCount()
time.sleep(1)
# 你的执行代码
e2 = cv.getTickCount()
ts = (e2 - e1)/ cv.getTickFrequency()
print ts,'(s)',ts*1e3,'(ms)',ts*1e6,'(us)',ts*1e9,'(ns)'
# 下面的示例应用中位数过滤，其内核的奇数范围为5到49。
img1 = cv.imread(imgpath('messi5.jpg'))
e1 = cv.getTickCount()
for i in range(5,49,2):
	img1 = cv.medianBlur(img1,i)
e2 = cv.getTickCount()
t = (e2 - e1)/cv.getTickFrequency()
print( t )
# 得到的结果是0.521107655秒
#
# 可以使用时间模块执行相同的操作。代替cv.getTickCount，使用time.time()函数。
# 然后取两次相差。


# **********
'''
OpenCV中的默认优化
许多 OpenCV 函数都是使用 SSE2、 AVX 等进行优化的。 它还包含未优化的代码。
因此，如果我们的系统支持这些特性，我们就应该利用它们(几乎所有现代的处理器都支持它们)。

可以使用 cv.useOptimized() 检查是否启用 / 禁用
cv.setUseOptimized(boolean) 以启用 / 禁用它。
'''
print cv.useOptimized()
cv.setUseOptimized(False)
print cv.useOptimized()
cv.setUseOptimized(True)
print cv.useOptimized()


# **********
'''
性能优化技术
有几种技术和编码方法可以充分利用 Python 和 Numpy 的最大性能。
要注意的主要事情是，首先尝试以一种简单的方式实现算法。一旦它运行起来，分析它，找到瓶颈并优化它们

几条原则：
1.尽量避免在Python中使用循环，尤其是双/三重循环等。它们本来就很慢。
2.由于Numpy和OpenCV已针对向量运算进行了优化，因此将算法/代码向量化到最大程度。
3.利用缓存一致性。
4.除非需要，否则切勿创建数组的副本。尝试改用视图。数组复制是一项昂贵的操作。
5.即使执行了所有这些操作后，如果你的代码仍然很慢，或者不可避免地需要使用大循环，请使用Cython等其他库来使其更快。
'''

